package tool
{
	import assets.Asset;
	
	import away3d.core.base.SubMesh;
	import away3d.materials.ColorMaterial;
	import away3d.materials.TextureMaterial;
	import away3d.materials.methods.AlphaMaskMethod;
	import away3d.materials.methods.FresnelEnvMapMethod;
	import away3d.textures.ATFCubeTexture;
	import away3d.textures.ATFTexture;
	import away3d.textures.PlanarReflectionTexture;
	
	import events.LoadedEvent;
	
	import flash.display.BlendMode;
	
	
	/**
	 * 所有模型都是通过它来赋予材质
	 * 现在也是唯一使用AssetAtfTexture和AssetAtfTextureWithZIP的地方
	 */
	public class MaterialGetter
	{
		private var _subMesh:SubMesh;
		private var _xml:XML;
		
		private var type:String;
		private var name:String;
		private var bothSides:Boolean;
		private var blendMode:String;
		
		private var color:uint;
		private var ambientColor:uint;
		private var specularColor:uint;
		private var specular:Number;
		private var gloss:Number;
		private var alpha:Number;
		private var alphaBlending:Boolean = false;
		private var simpleAlpha:Boolean = false;
		private var opaMed:Boolean = false;
		private var receiveShadow:Boolean = false;
		
		private var diffuseMapURL:String;
		private var opacityMapURL:String;
		private var specularMapURL:String;
		private var ambientMapURL:String;
		private var normalMapURL:String;
		private var reflectionXMLURL:String;
		private var reflectionMapURL:String;
		private var refXml:XML;
		
		private var difTexture:ATFTexture;
		private var opaTexture:ATFTexture;
		private var ambTexture:ATFTexture;
		private var speTexture:ATFTexture;
		private var norTexture:ATFTexture;
		
		private var refTexture:ATFCubeTexture;
		
		private var flatMirrorAmout:Number;
		private var reflectionTexture:PlanarReflectionTexture;
		
		private var allTex:uint=0;
		private var curTex:uint = 0;
		
		private var _onCompleted:Function;
		
		public function MaterialGetter(subMesh:SubMesh,xml:XML,onComplete:Function=null)
		{
			_subMesh = subMesh;
			_subMesh.material = new ColorMaterial;
			_xml = xml;
			
			_onCompleted = onComplete;
			
			type = xml.@type;
			name = xml.@name;
			bothSides =  xml.@bothSide=="1"?true:false;
			blendMode = xml.@blendMode=="add"?BlendMode.ADD:xml.@blendMode=="mult"?BlendMode.MULTIPLY:BlendMode.NORMAL;
			receiveShadow = xml.@receiveShadow=="true"?true:false;
			
			setupValues();
			setupTextures();
		}
		
		private function setupValues():void
		{
			var valstr:String = _xml.values;
			var valArray:Array = valstr.split(",");
			
			color = uint(valArray[0]);
			ambientColor = uint(valArray[1]);
			specularColor = uint(valArray[2]);
			specular = Number(valArray[3])/50;
			gloss = Number(valArray[4])*1.5;
			alpha = uint(valArray[5])/100;
			
			//			flatMirrorAmout = Number(_xml.flatMirror)/100;
			//			if(flatMirrorAmout>0)
			//			{
			//				var ref:PlanarReflectionTexture = new PlanarReflectionTexture;
			//				reflectionTexture = new PlanarReflectionTexture();
			//			}
		}
		
		private function setupTextures():void
		{
			var dif:String = _xml.diffuseMap;
			
			if(type=="texture")
			{
				allTex++;
				Asset.atfTextureWithZIP.addEventListener(LoadedEvent.TEXTURE_COMPLETE,diffuseMapLoaded);
				
				diffuseMapURL = Global.assetPath+"textures/"+ dif +".zip";
				Asset.atfTextureWithZIP.load(diffuseMapURL);
			}
			
			opacityMapURL = _xml.opacityMap;
			if(opacityMapURL != "0" && opacityMapURL != "")
			{
				if(_xml.opacityMap.@channel=="1" || _xml.opacityMap.@channel=="" )
				{
					if(_xml.@simpleAlpha == "false")alphaBlending = true
					else if(_xml.@simpleAlpha == "true")simpleAlpha = true;
				}
				else if(_xml.opacityMap.@channel=="2")
				{
					opaMed = true;
					allTex++;
					opacityMapURL=Global.assetPath+"textures/"+opacityMapURL +".zip";
					Asset.atfTextureWithZIP.addEventListener(LoadedEvent.TEXTURE_COMPLETE,opacityMapLoaded);
					Asset.atfTextureWithZIP.load(opacityMapURL);
				}
			}
			
			ambientMapURL = _xml.ambientMa;
			if(ambientMapURL != "0" && ambientMapURL != "")
			{
				allTex++;
				ambientMapURL=Global.assetPath+"textures/"+ambientMapURL +".zip";;
				Asset.atfTextureWithZIP.addEventListener(LoadedEvent.TEXTURE_COMPLETE,ambientMapLoaded);
				Asset.atfTextureWithZIP.load(ambientMapURL);
			}
			
			
			specularMapURL = _xml.specularMap;
			if(specularMapURL != "0" && specularMapURL != "")
			{
				allTex++;
				specularMapURL=Global.assetPath+"textures/"+specularMapURL +".zip";;
				Asset.atfTextureWithZIP.addEventListener(LoadedEvent.TEXTURE_COMPLETE,specularMapLoaded);
				Asset.atfTextureWithZIP.load(specularMapURL);
			}
			
			normalMapURL = _xml.normalMap;
			if(normalMapURL != "0" && normalMapURL != "")
			{
				allTex++;
				normalMapURL=Global.assetPath+"textures/"+normalMapURL +".zip";
				Asset.atfTextureWithZIP.addEventListener(LoadedEvent.TEXTURE_COMPLETE,normalMapLoaded);
				Asset.atfTextureWithZIP.load(normalMapURL);
			}
			
			reflectionMapURL = _xml.reflectionMap;
			if(reflectionMapURL!="0" && reflectionMapURL != "")
			{
				allTex++;
				reflectionMapURL=Global.assetPath+"textures/"+reflectionMapURL +".zip";
				
				Asset.atfTextureWithZIP.addEventListener(LoadedEvent.TEXTURE_COMPLETE,reflectionMapLoaded);
				Asset.atfTextureWithZIP.load(reflectionMapURL,true);
			}
			
			if(allTex==0)gotMat();
		}
		
		private function reflectionMapLoaded(e:LoadedEvent):void
		{
			if(e.URL==reflectionMapURL)
			{
				Asset.atfTextureWithZIP.removeEventListener(LoadedEvent.TEXTURE_COMPLETE,reflectionMapLoaded);
				refTexture =  Asset.resAtfTextures[reflectionMapURL];
				curTex++;
				if(curTex==allTex)gotMat();
			}
		}
		
		private function diffuseMapLoaded(e:LoadedEvent):void
		{
			if(e.URL==diffuseMapURL)
			{
				Asset.atfTextureWithZIP.removeEventListener(LoadedEvent.TEXTURE_COMPLETE,diffuseMapLoaded);
				difTexture = Asset.resAtfTextures[diffuseMapURL];
				curTex++;
				if(curTex==allTex)gotMat();
			}
		}
		
		private function opacityMapLoaded(e:LoadedEvent):void
		{
			if(e.URL==opacityMapURL)
			{
				Asset.atfTextureWithZIP.removeEventListener(LoadedEvent.TEXTURE_COMPLETE,opacityMapLoaded);
				opaTexture = Asset.resAtfTextures[opacityMapURL];
				curTex++;
				if(curTex==allTex)gotMat();
			}
		}
		private function ambientMapLoaded(e:LoadedEvent):void
		{
			if(e.URL==specularMapURL)
			{
				Asset.atfTextureWithZIP.removeEventListener(LoadedEvent.TEXTURE_COMPLETE,ambientMapLoaded);
				ambTexture = Asset.resAtfTextures[ambientMapURL];
				curTex++;
				if(curTex==allTex)gotMat();
			}
		}
		private function specularMapLoaded(e:LoadedEvent):void
		{
			if(e.URL==specularMapURL)
			{
				Asset.atfTextureWithZIP.removeEventListener(LoadedEvent.TEXTURE_COMPLETE,specularMapLoaded);
				speTexture = Asset.resAtfTextures[specularMapURL];
				curTex++;
				if(curTex==allTex)gotMat();
			}
		}
		
		private function normalMapLoaded(e:LoadedEvent):void
		{
			if(e.URL==normalMapURL)
			{
				Asset.atfTextureWithZIP.removeEventListener(LoadedEvent.TEXTURE_COMPLETE,normalMapLoaded);
				norTexture = Asset.resAtfTextures[normalMapURL];
				curTex++;
				if(curTex==allTex)gotMat();
			}
		}
		
		private function gotMat():void
		{
			var mat:*;
			if(type=="color")mat = new ColorMaterial(color,alpha)
			else 
			{
				mat = new TextureMaterial(difTexture,true,true);
				mat.alpha = alpha;
				mat.alphaBlending = alphaBlending;
				mat.alphaPremultiplied = true;
				if(simpleAlpha)mat.alphaThreshold = 0.9;
			}
			
			mat.name = name;
			mat.bothSides = bothSides;
			mat.ambientColor = ambientColor;
			mat.ambient = 1;
			mat.specularColor = specularColor;
			mat.specular = specular;
			mat.gloss = gloss;
			mat.blendMode = blendMode;
			
			//			var lm:LightMapDiffuseMethod = new LightMapDiffuseMethod(
			//			var lmm:LightMapMethod = new LightMapMethod(
			
			if(receiveShadow)mat.shadowMethod = Global.shadowMethod;
			if(ambTexture)mat.ambientTexture = ambTexture;
			if(speTexture)mat.specularMap = speTexture;
			if(norTexture)mat.normalMap = norTexture;
			
			if(refTexture)
			{
				var envMethod:FresnelEnvMapMethod = new FresnelEnvMapMethod(refTexture,1);
				mat.addMethod(envMethod);
				envMethod.fresnelPower = Number(_xml.reflectionMap.@falloff);
				envMethod.alpha =  Number(_xml.reflectionMap.@val1)/100;
				envMethod.normalReflectance = Number(_xml.reflectionMap.@val2)/100;
			}
			
			if(opaMed)
			{
				var alphaMed:AlphaMaskMethod = new AlphaMaskMethod(opaTexture,true);
				mat.addMethod(alphaMed);
				mat.alphaPremultiplied = true;
				mat.blendMode = BlendMode.ERASE;
			}
			
			//			mat.diffuseLightSources = LightSources.PROBES;
			//			mat.specularLightSources = LightSources.LIGHTS;
			
			//			mat.addMethod(Global.fogMethod);
			mat.lightPicker = Global.lightPicker;
			
			_subMesh.material = mat;
			if(_onCompleted!=null)_onCompleted();
		}
		
	}
}